/************************************************************************************
*  Copyright (c), 2020, LXG.
*
* FileName		:
* Author		:firestaradmin
* Version		:1.0
* Date			:2020.7.21
* Description	:串口接收BIN文件数据烧录至外部储存器
* History		:
*
*
*************************************************************************************
帧协议格式:
        Byte0	Byte1	Byte2		Byte3		Byte4		Byte5	…		last but two Byte	last but one Byte	Last Byte
        0xC5	0x5C	XX			XX			XX			XX		XX		XX					0x5C				0xC5
        帧头	帧头	命令		长度高字节	长度低字节	数据	数据	BCC校验码			帧尾				帧尾

        如发送数据：C5 5C 00 00 04 22 33 44 FF AE 5C C5
        BCC = 除了帧头帧尾和bcc本身的异或
        BCC = 00 ^ 00 ^ 04 ^ 22 ^ 33 ^ 44 ^ FF = AE

命令:	0x00	0x01			0x02			0xFF
备注:	数据	数据传输开始	数据传输结束	应答

*************************************************************************************/

#include "define.h"
#include "disp.h"
#include "power.h"
#include "clk.h"
#include "gpio.h"
#include "time.h"
#include "uart.h"
#include "spk.h"
#include "flash.h"
#include "adc.h"
#include "algo.h"
#include "bp.h"
#include "func.h"
#include "op.h"
#include "pwm.h"
#include "voice.h"
#include "queue.h"
#include "fasttest.h"
#include "inner_voice.h"
#include "uart_flash.h"
#include "w25qxx.h"
#include "transfer_BIN_to_EX_FLASH.h"

static u32 bytesStored = 0;          // 已经储存的字节
static u32 stroage_StartAddress = 0; // 片外储存的起始地址
static u8 transfer_started_flag = 0; // 是否已经开始传输数据标志

static u8 TBEF_recvBuf[512]; // 接受buf，最大单次传输字节数应不大于buf大小-8
static u16 TBEF_recvBuf_tail = 0;
volatile u8 flag_TBEF_decode = 0; 
volatile u8 TBEF_uart_recving_flag = 0;
volatile u8 TBEF_uart_recv_tim_cnt = 0;

void delay_ms(uint16 ms)
{
    volatile uint32_t cnt = 0;
    for (uint16 i = 0; i < ms; i++)
    {
        cnt = 777;
        while (cnt)
        {
            cnt--;
            nop4();
        }
    }
}

/**************************************************************************************
 * FunctionName   : UartSendMultByte()
 * Description    : 发送多字节数据
 * EntryParameter : str - 数据缓存; len - 数据长度
 * ReturnValue    : None
 **************************************************************************************/
void UartSendMultByte(u8 *pStr, u16 len)
{
    while (len--)
    {
        Rs232_SendByte(*pStr++); // 发送数据
    }
}

// 用户回调函数，此处修改需要烧录的函数
void TBEF_data_CallBack(u8 *dataBuf, u16 len)
{
    // 根据需求修改此处
    W25QXX_Write(dataBuf, stroage_StartAddress + bytesStored, len); // 写入flash

    bytesStored += len;
}

// 串口处理函数，在串口中断中调用，将接收到的字节传入data
void TBEF_uart_receive_process(void)
{
    if (UART_GetFlagStatus(UART1, UART_Flag_RXNE)) // 接收中断(接收到的数据必须是0x0d 0x0a结尾)
    {
        TBEF_recvBuf[TBEF_recvBuf_tail++] = UART_ReceiveData(UART1); // 存入缓存数组
        #if 00
		UART_SendData(UART1,TBEF_recvBuf[TBEF_recvBuf_tail - 1]);
        #endif
        if (TBEF_recvBuf_tail >= sizeof(TBEF_recvBuf))
        {
            TBEF_recvBuf_tail = sizeof(TBEF_recvBuf) - 1; // 防止数据量过大
        }
        TBEF_uart_recving_flag = 1;               // 串口 接收标志
        TBEF_uart_recv_tim_cnt = 0;               // 串口接收定时器计数清零
    }
}

// 定时器处理函数，在定时器中断中调用，1Ms一次
void TBEF_tim_process(void) // 1MS调用一次
{
    /* 串口接收完成判断处理 */
    TBEF_uart_recv_tim_cnt++;       // usart 接收计数
    if (TBEF_uart_recv_tim_cnt > 10 && TBEF_uart_recving_flag == 1) // 当超时 未接收到数据，则认为数据接收完成。
    {
        flag_TBEF_decode = 1;
        TBEF_uart_recving_flag = 0;
        TBEF_uart_recv_tim_cnt = 0;
    }
}

// 在主函数中调用，需要一直循环调用，此函数为阻塞函数
void TBEF_mainFun(void)
{
    // while(flag_TBEF_decode != 1);	//wait receive finish
    if (flag_TBEF_decode == 1)
    {
        u8 ret = TBEF_frameVerify();
        if (ret)
            TBEF_Err_Processing(ret);
        else
            TBEF_CMD_Precesing();
		delay_ms(10);
        TBEF_SendACK(ret);
        TBEF_recvBuf_tail = 0;
        flag_TBEF_decode = 0;
    }
    else
    {
        delay_ms(10);
        TBEF_tim_process();
    }
}

void TBEF_CMD_Precesing(void)
{
    u8 cmd = TBEF_recvBuf[2];

    if (cmd == 0x00)
    {
        u16 length = TBEF_recvBuf[3] * 0xFF + TBEF_recvBuf[4];
        TBEF_data_CallBack(TBEF_recvBuf + 5, length);
    }
    else if (cmd == 0x01)
    {
        transfer_started_flag = 1;
        bytesStored = 0;
        stroage_StartAddress = (uint32_t)TBEF_recvBuf[5] * 0x1000000 + (uint32_t)TBEF_recvBuf[6] * 0x10000 + (uint32_t)TBEF_recvBuf[7] * 0x100 + (uint32_t)TBEF_recvBuf[8];
        // stroage_StartAddress = ((uint32_t)TBEF_recvBuf[5] << 24) & ((uint32_t)TBEF_recvBuf[6] << 16) & ((uint32_t)TBEF_recvBuf[7] << 8) & (uint32_t)TBEF_recvBuf[8];
    }
    else if (cmd == 0x02)
    {
        transfer_started_flag = 0;
    }
    else
    {
        // TODO:
    }
}

void TBEF_Err_Processing(u8 err)
{
    #if 22
    return; //
    #endif
    switch (err)
    {
    case 0: /* no err */

        break;
    case 1:
        SendString("Frame Head err!\r\n");
        break;
    case 2:
        SendString("Frame Tail err!\r\n");
        break;
    case 3:
        SendString("BCC err!\r\n");
        break;
    default:
        SendString("Unknow err!\r\n");
    };
}

u8 TBEF_frameVerify(void)
{
    volatile u16 length = 0;
    u8 bcc = 0x00;

    if (TBEF_recvBuf[0] != 0xC5 && TBEF_recvBuf[1] != 0x5C)
    {
        return 1; // 帧头错误
    }

    length = (TBEF_recvBuf[3] << 8) | TBEF_recvBuf[4];
//    if (TBEF_recvBuf[2] == 0)
//    {
//        length -= 1;
//    }
    for (u16 i = 2; i < 5 + length; i++)
    {
        bcc ^= TBEF_recvBuf[i];
    }

    if (bcc != TBEF_recvBuf[5 + length])
    {
        return 2; // bcc校验码错误
    }

    if (TBEF_recvBuf[6 + length] != 0x5C && TBEF_recvBuf[7 + length] != 0xC5)
    {
        return 3; // 帧尾错误
    }

    return 0;
}

// 如：C5 5C FF 00 01 00 FE 5C C5	表示没有错误
u8 sendBuf[9] = {0};
void TBEF_SendACK(u8 ERROR)
{
    sendBuf[0] = 0xC5;
    sendBuf[1] = 0x5C;
    sendBuf[2] = 0x00;
    sendBuf[3] = 0x00;
    sendBuf[4] = 0x01;
    sendBuf[5] = 0x00;
    sendBuf[6] = 0x00;
    sendBuf[7] = 0x5C;
    sendBuf[8] = 0xC5;


    sendBuf[2] = TBEF_recvBuf[2];
    sendBuf[5] = ERROR;
    for (u16 i = 2; i < 6; i++)
    {
        sendBuf[6] ^= sendBuf[i];
    }
    UartSendMultByte(sendBuf, 9);
}


/*
//W25Q64
//容量为8M字节,共有128个Block,2048个Sector
//4Kbytes为一个Sector
//16个扇区为1个Block

//以下表示地址为W25QXX的第一个区块的第0个扇区的第0个地址
#define W25QXX_STORAGE_Block	1
#define W25QXX_STORAGE_Sector	0
#define W25QXX_STORAGE_Sector_OFFSET	0
//static u32 TBEF_W25QXX_StorageAddress = W25QXX_STORAGE_Block * 4 * 1024 * 16 + 4 * 1024 * W25QXX_STORAGE_Sector + W25QXX_STORAGE_Sector_OFFSET;	//要烧录的具体地址
*/
